package com.bstek.bdf4.investigate.service;


import com.bstek.bdf4.investigate.dao.CategoryJPADao;
import com.bstek.bdf4.investigate.dao.InvestigateDao;
import com.bstek.bdf4.investigate.dao.InvestigateJPADao;
import com.bstek.bdf4.investigate.entity.Category;
import com.bstek.bdf4.investigate.entity.Investigate;
import com.bstek.dorado.annotation.DataProvider;
import com.bstek.dorado.data.entity.EntityState;
import com.bstek.dorado.data.entity.EntityUtils;
import com.bstek.dorado.data.provider.Page;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.PageRequest;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Component
public class InvestigateService {

    @Autowired
    private InvestigateDao investigateDao;
    @Autowired
    private InvestigateJPADao investigateJPADao;
    @Autowired
    private CategoryJPADao categoryJPADao;

    // 查询所有数据不分页
    public Collection<Investigate> getAll(String type) {
        List<Investigate> investigateList = new ArrayList<>();
        if (Objects.equals("jpa",type)) {
            // 使用jpa查询
            investigateList = investigateJPADao.findAll();
            for (Investigate investigate : investigateList) {
                if (investigate.getCategoryId() != null) {
                    // 查询报告下的类别信息set到报告中
                    investigate.setCategory(categoryJPADao.findById(investigate.getCategoryId()).get());
                }
            }
        } else {
            // 使用springjdbcTemlate
            JdbcTemplate jdbcTemplate = investigateDao.getJdbcTemplate();
            String sql = "select id, title, author, category_id, name, content, other,create_user, create_time, modify_user, modify_time from investigate";
            investigateList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Investigate.class));
            for (Investigate investigate : investigateList) {
                if (investigate.getCategoryId() != null) {
                    Category category = jdbcTemplate.queryForObject("select id, category_name from category where id = ?", new Object[]{investigate.getCategoryId()}, new BeanPropertyRowMapper<>(Category.class));
                    investigate.setCategory(category);
                }
            }
        }
        return investigateList;
    }

    // 分页查询报告数据
    public void getByPage(Page<Investigate> page, Map<String, Object> params) {
        String title = null;
        String name = null;
        String type = null; // 标记使用springJdbcTemlate或者jpa查询
        if (params != null) {
            title = (String) params.get("title");
            name = (String) params.get("name");
            type = (String) params.get("type");
        }
        // 使用jpa查询
        if (Objects.equals(type,"jpa")) {
            Investigate investigate = new Investigate();
            investigate.setTitle(StringUtils.isNotBlank(title) ? title: null);
            investigate.setName(StringUtils.isNotBlank(name)? name : null);
            // 携带查询参数 title，name， 并分页
            ExampleMatcher matcher = ExampleMatcher.matching().withMatcher("title",ExampleMatcher.GenericPropertyMatchers.contains())
                    .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.contains());
            Example<Investigate> example = Example.of(investigate ,matcher);
            org.springframework.data.domain.Page<Investigate> investigatePage = investigateJPADao.findAll(example, PageRequest.of(page.getPageNo() -1 , page.getPageSize()));
            List<Investigate> investigateList = investigatePage.getContent();
            for (Investigate investigate1 : investigateList) {
                if (investigate1.getCategoryId() != null) {
                    // 查询了报告下分类set报告中
                    investigate1.setCategory(categoryJPADao.findById(investigate1.getCategoryId()).orElse(null));
                }
            }
            // 将数据装载到dorado的page对象中
            page.setEntities(investigateList);
            page.setEntityCount((int) investigatePage.getTotalElements());
        } else {
            // 使用springjdbcTemlate查询
            investigateDao.getByPage(page, title, name);
        }
    }

    /**
     * 保存数据
     * @param investigateList
     * @param type  标记使用springJdbcTemlate或者jpa查询
     */
    @Transactional
    public void save(Collection<Investigate> investigateList, String type) {
        String currentUserName = "";
        JdbcTemplate jdbcTemplate = investigateDao.getJdbcTemplate();
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (!(authentication instanceof AnonymousAuthenticationToken)) {
            currentUserName = authentication.getName();
        }
        // 使用jpa保存
        if (Objects.equals(type, "jpa")) {
            for (Investigate investigate : investigateList) {
                if (EntityState.DELETED.equals(EntityUtils.getState(investigate))) {
                    investigateJPADao.delete(investigate);
                } else if (EntityState.MODIFIED.equals(EntityUtils.getState(investigate))) {
                    investigate.setModifyUser(currentUserName);
                    investigate.setModifyTime(new Date());
                    investigateJPADao.save(investigate);
                } else if (EntityState.NEW.equals(EntityUtils.getState(investigate))) {
                    investigate.setCreateTime(new Date());
                    investigate.setCreateUser(currentUserName);
                    investigateJPADao.save(investigate);
                }
            }
        } else {
            // 使用springjdbcTemlate保存
            for (Investigate investigate : investigateList) {
                if (EntityState.DELETED.equals(EntityUtils.getState(investigate))) {
                    jdbcTemplate.update("delete from investigate where id = ? ", new Object[]{investigate.getId()});
                } else if (EntityState.MODIFIED.equals(EntityUtils.getState(investigate))) {
                    investigate.setModifyUser(currentUserName);
                    investigate.setModifyTime(new Date());
                    jdbcTemplate.update("update investigate set title = ?, author = ?, category_id = ?, name = ?, " +
                                    "content = ?, other = ?,modify_user = ?, modify_time = ? where id = ?"
                            , new Object[]{investigate.getTitle(), investigate.getAuthor(), investigate.getCategoryId(), investigate.getName(), investigate.getContent()
                                    , investigate.getOther(), currentUserName, investigate.getModifyTime(), investigate.getId()
                            });

                } else if (EntityState.NEW.equals(EntityUtils.getState(investigate))) {
                    investigate.setCreateTime(new Date());
                    investigate.setCreateUser(currentUserName);
                    jdbcTemplate.update("insert into investigate (title,author,category_id,name,content,other,create_user,create_time,modify_user,modify_time) values(?,?,?,?,?,?,?,?,?,?)", new Object[]{investigate.getTitle(), investigate.getAuthor(), investigate.getCategoryId(), investigate.getName(),
                            investigate.getContent(), investigate.getOther(), currentUserName, investigate.getCreateTime(), null, null
                    });

                }
            }
        }
    }

    /**
     * 通过分类查询该分类下报告
     */
    public void getInvestigateByCategoryId(Long id, Page<Investigate> page) {
        investigateDao.getInvestigateByCategoryId(page, id);
    }

    public Collection<Investigate> getInvestigateByCategoryId(Long id) {
        JdbcTemplate jdbcTemplate = investigateDao.getJdbcTemplate();
        String sql = "select id, title, author, category_id, name, content, other,create_user, create_time, modify_user, modify_time from investigate where category_id = ?";
        List<Investigate> investigateList = jdbcTemplate.query(sql, new Object[]{id}, new BeanPropertyRowMapper<>(Investigate.class));
        return investigateList;
    }
}


